package com.os.meituan.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

public class JsonClass {
    public static <T> String toJSON(T bean) {
        var objectMapper = getObjectMapper();
        try {
            return objectMapper.writeValueAsString(bean);
        } catch (JsonProcessingException e) {
            return null;
        }
    }

    // 输出不是null的字段
    public static <T> String toJSONWithNoNull(T bean) {
        var oMapper = getObjectMapper();
        oMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        try {
            return oMapper.writeValueAsString(bean);
        } catch (JsonProcessingException e) {
            return null;
        }
    }

//    public static <T> T fromJSON(String json, TypeReference<?> toValueTypeRef) {
//        ObjectMapper oMapper = new ObjectMapper();
//        oMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
//        oMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
//        oMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//        try {
//            return (T) oMapper.readValue(json, toValueTypeRef);
//        } catch (IOException e) {
//            return null;
//        }
//    }

    public static Map fromJSONToMap(String json) {
        var oMapper = getObjectMapper();
        oMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        oMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        try {
            return oMapper.readValue(json, Map.class);
        } catch (IOException e) {
            return null;
        }
    }

    public static <T> T fromJSON(String json, Class<T> modelclass) {
        var oMapper = getObjectMapper();
        try {
            return oMapper.readValue(json, modelclass);
        } catch (IOException e) {
            return null;
        }
    }

    public static <T> List<T> fromJSONToList(String json, Class<T> modelclass) {
        var oMapper = getObjectMapper();
        try {
            JavaType javaType = oMapper.getTypeFactory().constructParametricType(ArrayList.class, modelclass);
            return oMapper.readValue(json, javaType);
        } catch (IOException e) {
            return null;
        }
    }

    public static List<String> fromJSONToListString(String json) {
        var oMapper = getObjectMapper();
        try {
            JavaType javaType = oMapper.getTypeFactory().constructParametricType(ArrayList.class, String.class);
            return oMapper.readValue(json, javaType);
        } catch (IOException e) {
            return null;
        }
    }

    public static JsonNode toJSONObject(String str) {
        var oMapper = getObjectMapper();
        try {
            return oMapper.readTree(str);
        } catch (IOException e) {
            return null;
        }
    }

    private static ObjectMapper getObjectMapper() {
        var objectMapper = new ObjectMapper();

        //序列化的时候序列对象的所有属性
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);

        //反序列化的时候如果多了其他属性,不抛出异常
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        //如果是空对象的时候,不抛异常
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

        //取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        var dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFmt.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));

        objectMapper.setDateFormat(dateFmt);

        return objectMapper;
    }
}
